package com.alibaba.citrus.cr.order.open.api.facade.common.until;


import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.citrus.cr.common.exception.FacadeException;
import com.alibaba.citrus.cr.order.open.api.facade.common.model.WmsOrderMessageDTO;
import com.alibaba.citrus.cr.order.open.api.facade.model.TransferOrder;
import com.alibaba.fastjson.JSON;
import com.epoch.app.crunifiedinventory.sdo.enums.AllocateOrderTypeEnum;
import com.epoch.app.mninventorycenter.model.dto.*;
import com.google.common.collect.Lists;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

public class CheckUtil {


    /**
     * 调拨单，校验货品单位是否一致
     * @return str
     */
    public static String checkScItemTransferOrder(List<TransferOrderDetailRequest> transferOrderDetailList,
                                     Map<String, ScItemResponse> scItemInfoMap){
        StringBuilder errMsg = new StringBuilder();
        for(TransferOrderDetailRequest x:transferOrderDetailList){
            ScItemResponse scItemResponse = scItemInfoMap.get(x.getGoodsCode());
            if(!scItemInfoMap.containsKey(x.getGoodsCode())){
                return errMsg.append("货品编码:").append(x.getGoodsCode()).append("不存在").toString();
            }
            Map<String, String> features = scItemResponse.getFeatures();

            if(features == null){
                return errMsg.append("货品编码:").append(x.getGoodsCode()).append("单位不一致").toString();
            }
            if(!Objects.equals(features.get("unitName"),x.getUnit())){
                return  errMsg.append("货品编码:").append(x.getGoodsCode()).append("货品单位不一致").toString();
            }
        }
        return null;
    }

    /**
     * 货品状态，类型校验，是否是组合货品，是否可用
     * @param scItemInfoMap map
     * @return str
     */
    public static String getCheckScItemTypeAndStatus(Map<String, ScItemResponse> scItemInfoMap){
        if(CollectionUtil.isEmpty(scItemInfoMap.values())){

            return "货品不存在";
        }
        List<ScItemResponse> typeList = scItemInfoMap.values().stream().filter(x ->x.getType() == 1).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(typeList)){
            return "不支持组合货品";
        }
        // -1禁用 -2删除 不可用, 1可用
        List<String> statusList = scItemInfoMap.values().stream().filter(x ->x.getStatus() !=1).collect(Collectors.toList()).stream().map(ScItemResponse::getOuterId).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(statusList)){
            return "货品状态不可用: " + JSON.toJSONString(statusList);
        }

        return null;
    }

    /**
     * 货品状态，类型校验，是否是组合货品，是否可用
     * @param scItemInfoList map
     * @return str
     */
    public static String getCheckScItemTypeAndStatusList(List<ScItemResponse> scItemInfoList){

        if(CollectionUtils.isEmpty(scItemInfoList)){
            return "货品不存在";
        }
        List<ScItemResponse> typeList = scItemInfoList.stream().filter(x ->x.getType() == 1).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(typeList)){
            return "不支持组合货品";
        }
        // -1禁用 -2删除 不可用, 1可用
        List<ScItemResponse> statusList = scItemInfoList.stream().filter(x ->x.getStatus() !=1).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(statusList)){
            return "货品状态不可用";
        }
        return null;
    }

    /**
     * 预报单，校验货品单位是否一致
     * @param transferForecastOrderCreateDetails t
     * @param scItemInfoMap scItem
     * @return str
     */
    public static String checkTransferForecastOrderScItem(List<TransferForecastOrderCreateDetail> transferForecastOrderCreateDetails,
                                     Map<String, ScItemResponse> scItemInfoMap){
        for(TransferForecastOrderCreateDetail x:transferForecastOrderCreateDetails){
            ScItemResponse scItemResponse = scItemInfoMap.get(x.getGoodsCode());
            Map<String, String> features = scItemResponse.getFeatures();
            if(features == null){
                return "货品单位不一致";
            }
            if(!Objects.equals(features.get("unitName"),x.getUnit())){
                return "货品单位不一致";
            }
        }
        return null;
    }
    /**
     * 预报单修改，校验货品单位是否一致，状态类型校验
     * @param transferForecastOrderCreateDetails t
     * @param scItemInfoMap scItem
     * @return str
     */
    public static String checkUpdateTransferForecastOrderScItem(List<TransferForecastOrderUpdateDetail> transferForecastOrderCreateDetails,
                                                          Map<String, ScItemResponse> scItemInfoMap){
        List<ScItemResponse> typeList = scItemInfoMap.values().stream().filter(x ->x.getType() == 1).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(typeList)){
            return "不支持组合货品";
        }
        // -1禁用 -2删除 不可用, 1可用
        List<ScItemResponse> statusList = scItemInfoMap.values().stream().filter(x ->x.getStatus() !=1).collect(Collectors.toList());
        if(CollectionUtil.isNotEmpty(statusList)){
            return "货品状态不可用";
        }

        for(TransferForecastOrderUpdateDetail x:transferForecastOrderCreateDetails){
            ScItemResponse scItemResponse = scItemInfoMap.get(x.getGoodsCode());
            Map<String, String> features = scItemResponse.getFeatures();
            if(features == null){
                return "货品单位不一致";
            }
            if(!Objects.equals(features.get("unitName"),x.getUnit())){
                return "货品单位不一致";
            }
        }
        return null;
    }

    /**
     * 发货仓，收货仓，仓库类型，组织，公司校验
     * @param type 调拨单类型
     * @param receiveLogicWare 收货仓
     * @param deliveryLogicWare 发货仓
     * @return str
     */
    public static String checkWareHouse(Integer type,WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare){
        String receiveWareHouse = checkWareHouseInfo(receiveLogicWare);
        if(receiveWareHouse != null){
            return "该收货"+receiveWareHouse;
        }
        String deliveryWareHouse = checkWareHouseInfo(deliveryLogicWare);
        if(deliveryWareHouse != null){
            return "该发货"+deliveryWareHouse;
        }
        if(Objects.equals(AllocateOrderTypeEnum.PLAN.getType(),type)){
            return checkWareHousePlan(receiveLogicWare,deliveryLogicWare);
        }else if(Objects.equals(AllocateOrderTypeEnum.CROSS_COMPANY.getType(),type)){
            return checkWareHouseCrossCompany(receiveLogicWare,deliveryLogicWare);
        }else if(Objects.equals(AllocateOrderTypeEnum.SAME_COMPANY.getType(),type)){
            return checkWareHouseSameCompany(receiveLogicWare,deliveryLogicWare);
        }else if (Objects.equals(AllocateOrderTypeEnum.BETWEEN_WAREHOUSE.getType(), type)
         || Objects.equals(AllocateOrderTypeEnum.FREIGHT_YARD_PICKUP.getType(), type)){
            // TODO: 2024/1/10
            return null;
        } else {
            return "调拨单类型不正确";
        }
    }

    public static String checkWareHouse4Update(Integer type,WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare){
        if (receiveLogicWare != null) {
            String receiveWareHouse = checkWareHouseInfo(receiveLogicWare);
            if(receiveWareHouse != null){
                return "该收货"+receiveWareHouse;
            }
        }

        if (deliveryLogicWare != null) {
            String deliveryWareHouse = checkWareHouseInfo(deliveryLogicWare);
            if(deliveryWareHouse != null){
                return "该发货"+deliveryWareHouse;
            }
        }

        if(Objects.equals(AllocateOrderTypeEnum.PLAN.getType(),type)){
            return checkWareHousePlan4Update(receiveLogicWare,deliveryLogicWare);
        } else if (Objects.equals(AllocateOrderTypeEnum.BETWEEN_WAREHOUSE.getType(), type)
                || Objects.equals(AllocateOrderTypeEnum.FREIGHT_YARD_PICKUP.getType(), type)){
            return null;
        } else {
            return "调拨单类型不正确";
        }
    }

    /**
     * 校验仓库是否可用
     * @param warehouse warehouse
     * @return
     */
    public static String checkWareHouseInfo(WarehouseQueryResponse warehouse){
        if(warehouse == null){
            return "仓库不存在";
        }
        if(warehouse.getId() == null){
            return "仓库不存在";
        }
        // status 1 正常
        if(warehouse.getStatus() == null || warehouse.getStatus() != 1){
            return "仓库状态不可用";
        }
        return null;
    }

    /**
     * 计划调拨单仓库校验，发货仓为工厂类型，收货仓为共享仓，同时两个仓库为同一公司代码
     * mode 3:逻辑仓
     * type 2:共享仓，3销售单元仓，4退货仓，5工厂仓
     * @param receiveLogicWare 收货仓
     * @param deliveryLogicWare 发货仓
     * @return str
     */
    public static String checkWareHousePlan(WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare){
        //计划调拨： 发货仓为工厂类型，收货仓为共享仓，同时两个仓库为同一公司代码

        // 仓库类型
        if(!Objects.equals(receiveLogicWare.getType(),2)){
            return "收货仓不是共享仓";
        }
        if(!Objects.equals(deliveryLogicWare.getType(),5)){
            return "发货仓不是工厂类型";
        }
        // 公司代码
        /*String receiveCompany = getSapCompanyCode(receiveLogicWare.getFeatures());
        if(receiveCompany == null){
            return "收货仓公司代码不存在";
        }
        String deliveryCompany = getSapCompanyCode(deliveryLogicWare.getFeatures());
        if(deliveryCompany == null){
            return "发货仓公司代码不存在";
        }*/
        /*if(!Objects.equals(receiveCompany,deliveryCompany)){
            return "仓库不为同一公司代码";
        }*/
        return null;
    }

    public static String checkWareHousePlan4Update(WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare){
        //计划调拨： 发货仓为工厂类型，收货仓为共享仓，同时两个仓库为同一公司代码
        String receiveCompany = null;
        String deliveryCompany = null;
        // 仓库类型
        if (receiveLogicWare != null) {
            if(!Objects.equals(receiveLogicWare.getType(),2)){
                return "收货仓不是共享仓";
            }
            // 公司代码
            receiveCompany = getSapCompanyCode(receiveLogicWare.getFeatures());
            if(receiveCompany == null){
                return "收货仓公司代码不存在";
            }
        }

        if (deliveryLogicWare != null) {
            if(!Objects.equals(deliveryLogicWare.getType(),5)){
                return "发货仓不是工厂类型";
            }
            deliveryCompany = getSapCompanyCode(deliveryLogicWare.getFeatures());
            if(deliveryCompany == null){
                return "发货仓公司代码不存在";
            }
        }



        if (StringUtils.isNoneBlank(receiveCompany, deliveryCompany) && !Objects.equals(receiveCompany,deliveryCompany)){
            return "仓库不为同一公司代码";
        }
        return null;
    }

    /**
     * 同公司调拨：发货仓与收货仓类型为共享仓，同时两个仓库为不同销售组织，同为一个公司代码
     * @param receiveLogicWare 收货仓
     * @param deliveryLogicWare 发货仓
     * @return str
     */
    public static String checkWareHouseSameCompany(WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare){

        // 仓库类型
        if(!Objects.equals(receiveLogicWare.getType(),2)){
            return "收货仓不是共享仓";
        }
        if(!Objects.equals(deliveryLogicWare.getType(),2)){
            return "发货仓不是共享仓";
        }
        // 销售组织
        String receiveSapOrgId = getSapOrgId(receiveLogicWare.getFeatures());
        if(StringUtils.isBlank(receiveSapOrgId)){
            return "发货仓销售组织不存在";
        }
        String deliverySapOrgId = getSapOrgId(deliveryLogicWare.getFeatures());
        if(StringUtils.isBlank(deliverySapOrgId)){
            return "收货仓销售组织不存在";
        }
        if(!Objects.equals(receiveSapOrgId,deliverySapOrgId)){
            return "仓库销售组织不相同";
        }

        // 公司代码
        String receiveCompany = getSapCompanyCode(receiveLogicWare.getFeatures());
        if(receiveCompany == null){
            return "收货仓公司代码不存在";
        }
        String deliveryCompany = getSapCompanyCode(deliveryLogicWare.getFeatures());
        if(deliveryCompany == null){
            return "发货仓公司代码不存在";
        }
        if(!Objects.equals(receiveCompany,deliveryCompany)){
            return "仓库不为同一公司代码";
        }
        return null;
    }
    /**
     * 跨公司调拨： 收货仓与发货仓公司代码与销售组织均相同
     * @param receiveLogicWare 收货仓
     * @param deliveryLogicWare 发货仓
     * @return str
     */
    public static String checkWareHouseCrossCompany(WarehouseQueryResponse receiveLogicWare,WarehouseQueryResponse deliveryLogicWare){

        // 仓库类型
        if(!Objects.equals(receiveLogicWare.getType(),2)){
            return "收货仓不是共享仓";
        }
        if(!Objects.equals(deliveryLogicWare.getType(),2)){
            return "发货仓不是共享仓";
        }
        // 销售组织
        String receiveSapOrgId = getSapOrgId(receiveLogicWare.getFeatures());
        if(StringUtils.isBlank(receiveSapOrgId)){
            return "发货仓销售组织不存在";
        }
        String deliverySapOrgId = getSapOrgId(deliveryLogicWare.getFeatures());
        if(StringUtils.isBlank(deliverySapOrgId)){
            return "收货仓销售组织不存在";
        }
        if(Objects.equals(receiveSapOrgId,deliverySapOrgId)){
            return "仓库销售组织相同";
        }

        // 公司代码
        String receiveCompany = getSapCompanyCode(receiveLogicWare.getFeatures());
        if(receiveCompany == null){
            return "收货仓公司代码不存在";
        }
        String deliveryCompany = getSapCompanyCode(deliveryLogicWare.getFeatures());
        if(deliveryCompany == null){
            return "发货仓公司代码不存在";
        }
        if(!Objects.equals(receiveCompany,deliveryCompany)){
            return "仓库公司代码不相同";
        }
        return null;
    }

    /**
     * 货区公司编码
     * @param features features
     * @return str
     */
    private static String getSapCompanyCode(Map<String, String> features ){
        if(features == null){
            return "公司代码不存在";
        }
        return features.get("sapCompanyCode");
    }

    /**
     * 货区公司编码
     * @param features features
     * @return str
     */
    private static String getSapOrgId(Map<String, String> features ){
        if(features == null){
            return "销售组织不存在";
        }
        return features.get("sapOrgId");
    }

    /**
     * 回复接口仓库校验
     * @return replay
     */
    public static String checkReplyWareHouse(WarehouseQueryResponse wareHouse){

        //状态校验
        String s = checkWareHouseInfo(wareHouse);
        if(s !=null){
            return s;
        }
        if(!Objects.equals(wareHouse.getType(),2)){
            return "发货仓不是共享仓";
        }
        return null;
    }


    public static AllocateOrderTypeEnum getAllocateOrderTypeEnumType(Integer type) {
        for (AllocateOrderTypeEnum menu : AllocateOrderTypeEnum.values()) {
            if (Objects.equals(menu.getType(),type)) {
                return menu;
            }
        }
        return null;
    }


    /**
     * 时间格式校验
     * @param sDate sDate
     * @return 正确 true
     */
    public static boolean isLegalDateNew(String sDate) {

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date date = formatter.parse(sDate);
            return sDate.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 日期格式校验
     * @param sDate sDate
     * @return 正确 true
     */
    public static boolean isLegalDate(String sDate) {

        DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        try {
            Date date = formatter.parse(sDate);
            return sDate.equals(formatter.format(date));
        } catch (Exception e) {
            return false;
        }
    }

    public static Date strToDate(String strDae) {
        if(StringUtils.isBlank(strDae)){
            return null;
        }
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = null;
        try {
            parse = df.parse(strDae);
        } catch (ParseException e) {
            throw new FacadeException("时间格式转换异常");
        }
        return parse;
    }




    //  铁运、海运
    public static final List<Integer> shipMethodList = Lists.newArrayList(2, 3);

    /**
     * 校验是否需要创建货场提货单
     * @param orderInfo 调拨单
     * @return boolean
     */
    public static Boolean checkCreateFreightYardTransfer(TransferOrder orderInfo) {
        if (AllocateOrderTypeEnum.PLAN.getType().toString().equals(orderInfo.getTransferOrderType()) && shipMethodList.contains(orderInfo.getShipMethod())
                && StringUtils.isNotBlank(orderInfo.getTransferWarehouseId()) && Boolean.FALSE.equals(orderInfo.getReturnOrder())) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }
}
